package com.kepler.social.domain.user.security;

import com.kepler.social.common.constants.Enums;
import com.kepler.social.common.constants.TipsConst;
import com.kepler.social.common.utils.ValidateAssert;
import com.kepler.social.usersecurity.dao.domain.UserEmail;
import com.kepler.social.usersecurity.dao.domain.UserMobilePhone;
import com.kepler.social.usersecurity.dao.domain.UserPassword;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Objects;

/**
 * 注意：
 * 邮件只允许被注册一次，因为邮件一般是和人绑定的。所以，相同的用户可以修改回原来的邮箱。
 * 手机可以被多次注册，手机号注销后会被其他人再次使用。
 */
@Getter
@Setter
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public class UserSecurityAggregate {

    private UserPassword root;

    private UserMobilePhone phone;

    private UserEmail email;

    UserSecurityAggregate(UserPassword root) {
        this.root = root;
    }

    UserSecurityAggregate(UserPassword root, UserEmail email) {
        this(root);
        this.email = email;
    }

    UserSecurityAggregate(UserPassword root, UserMobilePhone phone) {
        this(root);
        this.phone = phone;
    }

    /**
     * 验证手机的有效性
     */
    public void checkMobilePhoneInUse() {
        ValidateAssert.notNull(this.root, TipsConst.user_not_exists);
        ValidateAssert.notNull(this.phone, TipsConst.mobile_phone_not_exists);
        ValidateAssert.isTrue(this.phone.getState() == Enums.UserMobilePhoneStateEnum.USED.getCode(),
                TipsConst.mobile_phone_not_exists);
    }

    public void checkMobilePhoneNotInUse() {
        ValidateAssert.isTrue(!isMobilePhoneInUse(), TipsConst.mobile_phone_exists);
    }

    public boolean isMobilePhoneInUse() {
        return isMobilePhoneExist() && this.phone.getState() == Enums.UserMobilePhoneStateEnum.USED.getCode();
    }

    public boolean isMobilePhoneExist() {
        return Objects.nonNull(this.root) && Objects.nonNull(this.phone);
    }

    public boolean isMobilePhoneToBeVerify() {
        return isMobilePhoneExist() && this.phone.getState() == Enums.UserMobilePhoneStateEnum.NOT_VERIFIED.getCode();
    }

    /**
     * 验证邮箱的有效性
     */
    public void checkEmailInUse() {
        ValidateAssert.notNull(this.root, TipsConst.user_not_exists);
        ValidateAssert.notNull(this.email, TipsConst.email_not_exists);
        ValidateAssert.isTrue(this.email.getState() != Enums.UserEmailStateEnum.NOT_VERIFIED.getCode(),
                TipsConst.email_not_exists);
        ValidateAssert.isTrue(this.email.getState() != Enums.UserEmailStateEnum.DISUSED.getCode(),
                TipsConst.email_disused);
    }


    public void checkEmailIntegrity() {
        ValidateAssert.isTrue(Objects.isNull(email) && Objects.isNull(root)
                        || Objects.nonNull(email) && Objects.nonNull(root),
                TipsConst.system_error_data_not_integrity);
    }

    /**
     * 检验有效是否可以被注册使用
     */
    public void checkEmailCanBeRegistered() {
        checkEmailIntegrity();
        ValidateAssert.isTrue(!isEmailExist() || isEmailToBeVerify(), TipsConst.email_used);
    }

    public boolean isEmailExist() {
        checkEmailIntegrity();
        return Objects.nonNull(this.email);
    }

    public boolean isEmailToBeVerify() {
        return isEmailExist() && this.email.getState() == Enums.UserEmailStateEnum.NOT_VERIFIED.getCode();
    }

}
